# -*- coding: utf-8 -*-
# This code written by ChanGOGOGO
"""
呼出历史数据
"""
import pymysql
from util import (
    date_slice,
    query_es,
    logging,
    time,
    ms2min,
    write_excel,
    session_status_infos,
    callout_connect_status_infos,
    db_ip,
    db_port,
    db_username,
    db_password,
    per_excel_data_num,
    dialog_signoff_trigger_infos,
    excel_save_dir,
)


class ExportCallOutHistory:
    def __init__(self, ui_data):
        self.data_date = ui_data.get("data_date")
        self.task_ids = ui_data.get("target_datas")
        self.business = ui_data.get("business")
        self.data_type = ui_data.get("data_type")
        self.call_type = ui_data.get("call_type")
        self.start_time = ui_data.get("start_time")
        self.end_time = ui_data.get("end_time")
        company_id = ui_data.get("company_id")
        self.db_name = f"yicall_{company_id}"
        self.table_index = ui_data.get("business_id")
        self.es_index = (
            f"{self.db_name}_{self.table_index}_callout_session_ach_{self.data_date}"
        )
        self.conn = pymysql.connect(
            host=db_ip,
            port=db_port,
            user=db_username,
            passwd=db_password,
            charset="utf8",
        )
        self.cursor = self.conn.cursor()

    def get_handled_data(self):
        #  从数据库中查询任务对应的任务名、场景名，因为终止任务未拨打的号码无法从es中获取任务名、场景名
        sql = f"""select a.task_id,a.task_name,a.dialog_voice_template_name,b.scene_name 
        from {self.db_name}.b_{self.table_index}_callout_task a 
        INNER JOIN {self.db_name}.b_{self.table_index}_call_scene b on a.scene_id=b.scene_id;"""
        self.cursor.execute(sql)
        query_result = self.cursor.fetchall()
        task_infos = dict()
        for x in query_result:
            task_id, task_name, dialog_voice_template_name, scene_name = x
            task_infos[task_id] = {
                "task_name": task_name,
                "dialog_voice_template_name": dialog_voice_template_name,
                "scene_name": scene_name,
            }
        self.cursor.close()
        self.conn.cursor()
        # 从es中查询数据
        task_id_num = len(self.task_ids)
        # 生成查询条件
        es_data = list()
        fields = [
            "customerCaseId",
            "dialNumber",
            "dialNumDistrict",
            "sessionStatus",
            "taskId",
            "calloutConnectStatus",
            "calloutLastNodeName",
            "calloutDialTime",
            "calloutStartTime",
            "calloutFinishTime",
            "dialogDuration",
            "dialogSignoffTrigger",
            "sessionId",
            "systemError",
            "systemErrorDesc",
            "calloutDialNumber",
            "calloutNumDistrict",
            "dialogUserPreferList",
            "dialogBotTurnCount",
            "dialogCustomerTurnCount",
        ]
        # 以“天”为单位查询es数据，避免scroll超时
        query_es_start_time = time.time()
        date_slice_result = date_slice(self.start_time, self.end_time)
        for everyday in date_slice_result:
            day_start_time = everyday[0]
            day_end_time = everyday[1]
            if task_id_num == 0:
                body = {
                    "query": {
                        "bool": {
                            "must": [
                                {
                                    "range": {
                                        "calloutFinishTime": {
                                            "gte": day_start_time,
                                            "lte": day_end_time,
                                        }
                                    }
                                }
                            ]
                        }
                    },
                    "sort": {"calloutDialTime": {"order": "asc"}},
                }
            else:
                body = {
                    "query": {
                        "bool": {
                            "must": [
                                {"terms": {"taskId": self.task_ids}},
                                {
                                    "range": {
                                        "calloutFinishTime": {
                                            "gte": day_start_time,
                                            "lte": day_end_time,
                                        }
                                    }
                                },
                            ]
                        }
                    },
                    "sort": {"calloutDialTime": {"order": "asc"}},
                }
            one_day_es_data = query_es(self.es_index, body, fields)
            es_data += one_day_es_data
        query_es_end_time = time.time()
        query_es_take_time = query_es_end_time - query_es_start_time
        logging.info(f"查询{self.es_index}共计耗时{query_es_take_time:.2f}秒。")
        total_count = len(es_data)  # es查询出的结果总量
        handle_data_start_time = time.time()
        handled_data = list()
        if total_count >= 1:
            for data in es_data:
                customer_case_id = data.get("customerCaseId")
                dial_number = data.get("dialNumber")
                dial_num_district = data.get("dialNumDistrict")
                session_status = data.get("sessionStatus")
                finally_session_status = session_status_infos.get(
                    int(session_status)
                )  # 会话状态枚举获取值
                task_id = data.get("taskId")
                task_name = task_infos.get(int(task_id)).get(
                    "task_name"
                )  # 从数据库查询结果中获取人物名
                scene_name = task_infos.get(int(task_id)).get(
                    "scene_name"
                )  # 从数据库查询结果中获取场景名
                dialog_voice_template_name = task_infos.get(int(task_id)).get(
                    "dialog_voice_template_name"
                )
                callout_connect_status = data.get("calloutConnectStatus")
                finally_callout_connect_status = callout_connect_status_infos.get(
                    int(callout_connect_status)
                )  # 呼叫状态
                callout_last_node_name = data.get("calloutLastNodeName")
                callout_dial_time = data.get("calloutDialTime")
                callout_start_time = data.get("calloutStartTime")
                callout_finish_time = data.get("calloutFinishTime")
                dialog_duration_ms = data.get("dialogDuration")
                dialog_duration_min = ms2min(int(dialog_duration_ms))  # 时长毫秒转分钟
                dialog_signoff_trigger = data.get("dialogSignoffTrigger")
                finally_dialog_signoff_trigger = dialog_signoff_trigger_infos.get(
                    int(dialog_signoff_trigger)
                )  # 挂断者枚举
                session_id = data.get("sessionId")
                db_index = self.db_name.split("_")[-1]
                finally_session_id = (
                    f"{db_index}_{self.table_index}_{session_id}"  # session_id
                )
                system_error = data.get("systemError")
                system_error_desc = data.get("systemErrorDesc")
                line_number = data.get("calloutDialNumber")
                callout_num_district = data.get("calloutNumDistrict")
                dialog_user_prefer = data.get("dialogUserPreferList")
                if dialog_user_prefer:
                    dialog_user_prefer = ",".join(dialog_user_prefer)
                dialog_bot_turn_count = data.get("dialogBotTurnCount")
                dialog_customer_turn_count = data.get("dialogCustomerTurnCount")
                handled_data.append(
                    [
                        customer_case_id,
                        dial_number,
                        dial_num_district,
                        finally_session_status,
                        task_id,
                        task_name,
                        scene_name,
                        dialog_voice_template_name,
                        finally_callout_connect_status,
                        callout_last_node_name,
                        callout_dial_time,
                        callout_start_time,
                        callout_finish_time,
                        dialog_duration_min,
                        finally_dialog_signoff_trigger,
                        finally_session_id,
                        system_error,
                        system_error_desc,
                        line_number,
                        callout_num_district,
                        dialog_user_prefer,
                        dialog_bot_turn_count,
                        dialog_customer_turn_count,
                    ]
                )
        handle_data_end_time = time.time()
        handle_data_take_time = handle_data_end_time - handle_data_start_time
        logging.info(
            f"处理从ElasticSearch中查询出来的数据共计耗时{handle_data_take_time:.2f}秒。"
        )
        return handled_data

    def export(self):
        handled_data = self.get_handled_data()  # 从es中查询数据
        total_count = len(handled_data)
        if total_count < 1:
            msg = (
                f"<font color=green>无法导出“{self.business}”的【{self.data_type}】，"
                f"原因：\n在{self.start_time}至{self.end_time}没有{self.call_type}数据！</font>"
            )
            logging.warning(msg)
            return {"code": 1, "total_data": 0, "excel_names": [], "msg": msg}
        else:
            write_excel_start_time = time.time()
            excel_title = [
                "caseID",
                "客户号码",
                "客户号码归属地",
                "会话状态",
                "任务ID",
                "任务名",
                "场景",
                "录音包",
                "呼叫状态",
                "挂断节点",
                "拨打时间",
                "拨通时间",
                "完成时间",
                "通话时长(分)",
                "挂断者",
                "sessionID",
                "异常码",
                "异常描述",
                "AI号码",
                "AI号码归属地",
                "客户意向",
                "机器人对话轮次",
                "客户对话轮次",
            ]
            excel_names = list()
            excel_batches = (
                total_count + per_excel_data_num - 1
            ) // per_excel_data_num  # 计算需要多少个excel存储数据
            data_index = 0
            for i in range(excel_batches):
                single_excel_data = handled_data[
                    data_index : data_index + per_excel_data_num
                ]
                data_index += per_excel_data_num
                sheet_infos = [[self.data_type, excel_title, single_excel_data]]
                if excel_batches > 1:
                    file_name = f"{self.business}_{self.data_type}_第{i + 1}批"
                else:
                    file_name = f"{self.business}_{self.data_type}"
                excel_name = write_excel(sheet_infos, excel_save_dir, file_name, True)
                excel_names.append(excel_name)
            write_excel_end_time = time.time()
            write_excel_take_time = write_excel_end_time - write_excel_start_time
            logging.info(
                f"将{self.business}的{self.data_type}写入excel共计耗时{write_excel_take_time:.2f}秒。"
            )
            return {"code": 0, "excel_names": excel_names, "msg": None}


if __name__ == "__main__":
    ...
